﻿// <copyright file="SmffHeader.cs" company="Sinclair Community College">
// Copyright 2010 Sinclair Community College
// </copyright>
// <originalAuthor>Patrick S. Seymour (patrick.seymour@gmail.com)</originalAuthor>

namespace SinclairCC.AppV
{
    using System;

    /// <summary>
    /// This class represents the SFT Header (SMFF) section in an App-V SFT/DSFT file.
    /// </summary>
    /// <remarks>
    /// The SFT header section starts the normal (non-differential) SFT file.
    /// </remarks>
    public class SmffHeader : HeaderMetadataSection
    {
        /// <summary>
        /// The internal version number for the package.
        /// </summary>
        /// <remarks>This value is initialized to 1 and monotonically increases by 1 each
        /// time the package is saved. For packages created in version 4.5 and upwards of
        /// App-V, this package version number is also applied to all files that have been
        /// changed since the previous version. See the CompressedIndexHeader (CIDX) class
        /// for more information on file versions.</remarks>
        private int packageVersion;

        /// <summary>
        /// The original creation timestamp for the package file.
        /// </summary>
        /// <remarks>In the SFT file, this value is stored as a Win32 FILETIME structure.
        /// The format is the UTC (GMT) time zone.</remarks>
        private DateTime creationTimeStamp;

        /// <summary>
        /// The last modification timestamp for the package file.
        /// </summary>
        /// <remarks>In the SFT file, this value is stored as a Win32 FILETIME structure.
        /// The format is the UTC (GMT) time zone.</remarks>
        private DateTime modificationTimeStamp;

        /// <summary>
        /// Initializes a new instance of the SmffHeader class.
        /// </summary>
        /// <param name="fileReader">
        /// A binary file reader that points to the SFT file.
        /// </param>
        public SmffHeader(System.IO.BinaryReader fileReader)
            : base(fileReader)
        {            
        }

        /// <summary>
        /// Gets the internal version number for the package.
        /// </summary>
        public int PackageVersion
        {
            get
            {
                this.ReadSection();
                return this.packageVersion;
            }
        }

        /// <summary>
        /// Gets the original creation timestamp for the package file.
        /// </summary>
        /// <remarks>
        /// The format is the UTC (GMT) time zone.
        /// </remarks>
        public DateTime CreationTimeStamp
        {
            get
            {
                this.ReadSection();
                return this.creationTimeStamp;
            }
        }

        /// <summary>
        /// Gets the last modification timestamp for the package file.
        /// </summary>
        /// <remarks>
        /// The format is the UTC (GMT) time zone.
        /// </remarks>
        public DateTime ModificationTimeStamp
        {
            get
            {
                this.ReadSection();
                return this.modificationTimeStamp;
            }
        }

        /// <summary>
        /// Reads the actual data for this section from the file.
        /// </summary>
        protected override void ReadSection()
        {
            if (this.SectionHasBeenRead)
            {
                return;
            }

            // Seek to the start of the data area for this section.
            long currentPosition = FileReader.BaseStream.Position;
            FileReader.BaseStream.Seek(this.StartPositionInFile + CommonSectionHeader.HeaderSize, System.IO.SeekOrigin.Begin);

            // Read the properties from the file.
            this.packageVersion = FileReader.ReadInt32();
            this.creationTimeStamp = DateTime.FromFileTimeUtc(FileReader.ReadInt64());
            this.modificationTimeStamp = DateTime.FromFileTimeUtc(FileReader.ReadInt64());

            this.SectionHasBeenRead = true;
            FileReader.BaseStream.Seek(currentPosition, System.IO.SeekOrigin.Begin);
        }
    }
}
